#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

int main(void) {
    // 创建GLFW窗体
    GLFWwindow* window;
    if (!glfwInit()) return -1; // 初始化GLFW
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); // 初始化一个窗口并且获取它的OpenGL上下文
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window); // Make the window's context current

    // 初始化GLEW
    // GLEW是一个跨平台的OpenGL封装库, 用于整合多平台OpenGLAPI的使用
    // 根据文档所述GLEW初始化必须在创建完一个OpenGL上下文后进行
    // https://glew.sourceforge.net/basic.html -> Initializing GLEW
    // GLEW初始化阶段需要在C++预处理器中传入 Processor Definitions -> "GLEW_STATIC"
    GLenum err = glewInit();
    if (GLEW_OK != err) { std::cout << err << std::endl; }
    std::cout << glGetString(GL_VERSION) << std::endl; // 通过GLEW调用OpenGLAPI实现跨平台的目的

    // 创建/设置顶点缓冲区 VRAM
    float vertexPosisitons[6] = {
        -0.5f, -0.5f,
         0.0f,  0.5f,
         0.5f, -0.5f,
    };
    unsigned int vertexBuffer; // 定义一个无符号整形buffer
    glGenBuffers(1, &vertexBuffer); // 使用API创建OpenGLBuffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); // 使用API给状态机绑定当前操作的buffer
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertexPosisitons, GL_STATIC_DRAW); // 给buffer添加数据
    // 指定缓冲区的布局 setting layout of buffers
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
    // glVertexAttribPointer API 参数详细解释
    // index 属性顺序, size 大小, type 类型, if_normalize 是否01标准化, stride 该顶点attributes占用buffer大小, float 偏移

    // 重复渲染循环直到关闭了窗口 Render here
    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);

        // DrawCall CPU通知GPU使用着色器程序绘制
        glDrawArrays(GL_TRIANGLES, 0, 3);
        // 为什么未编写Shader着色程序也能显示白色三角形? 为方便调试一般在显卡厂商的驱动中包含了默认的Shader程序

        glfwSwapBuffers(window); // Swap front and back buffers
        glfwPollEvents(); // Poll for and process events
    }

    glfwTerminate();
    return 0;
}